#include "expression.h"
#include <QTimer>
#include "globals.h"

CExpression::CExpression(QString n):Name(n)
{
}

void CExpression::addRecipient(CRecipient* rep)
{
    Recipients.push_back(rep);
};

void CExpression::SendSMS(QString Message)
{
    if (!sendTime.isNull())
        if (sendTime .secsTo(QDateTime::currentDateTime())< 5*60 ) return; //отправлять однотипные сообщения можно только раз в 5 минут.

    sendTime = QDateTime::currentDateTime();

    CRecipient *rep;

    QFile file(globals->SMSLogFilename);
    if (file.open(QIODevice::Append))
    {
        QString timestamp = QDateTime::currentDateTime().toString("[ d.MM.yyyy h:mm:ss ] - ");
        QString logString = timestamp +  Message + "\n";
        file.write(logString.toAscii());
        file.close();
    }

    foreach(rep,Recipients)
        globals->queueAddMessage(Message,rep->phone);

};

enum CheckStage
{
    St_Initial,
    St_Check_OnOff,
    St_Wait_Timer,
    St_Send_SMS,
    St_Inactive
};

double abs(double v)
{
    if (v<0) return -v;
    return v;
}

class COsmosExpression: public CExpression
{

    CTechParameter *conduct;
    CTechParameter *enable;
    double alarmValue;
    bool enableFlag;
    unsigned int checkTime;
    QTimer timer;
    QString Message;

    CheckStage stage;
    unsigned int smsCounter;
    double checkValue;

    bool isOffFlag;

public:
    COsmosExpression(QString msg,CTechParameter *cond, CTechParameter * enbl,double av,unsigned int ctime):
            CExpression("osmos"),
            conduct(cond),
            enable(enbl),
            alarmValue(av),
            enableFlag(false),
            checkTime(ctime),
            Message(msg),
            stage(St_Initial)

    {};
   virtual  void check()
    {
        bool isenabled = enable->getValue() > 1.0;


        if (!isenabled)
        {
            enableFlag = false;
            timer.stop();
            stage = St_Initial;
            return;
        }
        timer.setSingleShot(true);

        switch(stage)
        {
        case St_Inactive:
            return;

        case St_Initial:
            //Сбрасываем счетчик отправок смс.
            smsCounter=0;
            //Запускаем проверку на включенность осмоса.
            checkValue = conduct->getValue();
            stage = St_Check_OnOff;
            timer.setInterval(1 * 60 * 1000);  //1 minute
            timer.start();
            isOffFlag = true;

            return;
        case St_Check_OnOff:
            if (abs(checkValue - conduct->getValue()) > 0.001)
            {
                isOffFlag = false;
            }
            //проверяем временной интервал.
            if (timer.isActive()) return;

            //выполняем проверку на включенность.
            if (isOffFlag)
            {
                    SendSMS("Osmos off");
                    stage = St_Inactive;
                    return;
            }
            //Запускаем ожидание выхода на режим.
            timer.setInterval(checkTime * 60 * 1000);
            timer.start();
            stage = St_Wait_Timer;
            return;
        case St_Wait_Timer:
            //проверяем временной интервал.
            if (timer.isActive()) return;
            //Выполняем проверку параметра.
            if (conduct->getValue() > alarmValue)
            {
                //Запускаем отправку смс
                stage = St_Send_SMS;
            }
            return;
        case St_Send_SMS:
            if (smsCounter > 3)
            {
                stage = St_Inactive;
                return;
            }
            else
            {
                //Выполняем отправку смс.
                QString msg = Message + QString("value=%1").arg(conduct->getValue());
                SendSMS(msg);
                //Увеличиваем счетчик отправок.
                smsCounter ++;
                //Запускаем ожидание выхода на режим.
                timer.setInterval(10 * 60 * 1000); //10 min
                timer.start();
                //Выставляем ожидание повторной проверки параеметра.
                stage = St_Wait_Timer;
                return;
            }
            return;
          default:
            stage = St_Inactive;
            return;

        }

 //       enableFlag = true;

   //   timer.setInterval(checkTime * 60 * 1000); //30 min
   //   timer.setSingleShot(true);
   //   timer.start();
        return;
    };
};






CExpression * CExpression::createOsmos(QString message,CTechParameter *pressure, CTechParameter * enable,double alarmvalue, unsigned int ctime)
{
    return new COsmosExpression(message,pressure,enable,alarmvalue,ctime);
};
